#define _BSD_SOURCE
#ifdef _GNU_SOURCE
#define HAD_SOURCE
#undef _GNU_SOURCE
#endif
#include <stdio.h>
#ifdef HAD_SOURCE
#undef HAD_SOURCE
#define _GNU_SOURCE
#endif
#include "stdio_impl.h"
#include <limits.h>
#include <errno.h>

off_t __ftello_unlocked(FILE *f)
{
    off_t pos = f->seek(f, 0,
        (f->flags & F_APP) && f->wpos != f->wbase
        ? SEEK_END : SEEK_CUR);
    if (pos < 0) return pos;

    /* Adjust for data in buffer. */
    if (f->rend)
        pos += f->rpos - f->rend;
    else if (f->wbase)
        pos += f->wpos - f->wbase;
    return pos;
}

off_t __ftello(FILE *f)
{
    off_t pos;
    FLOCK(f);
    pos = __ftello_unlocked(f);
    FUNLOCK(f);
    return pos;
}

long ftell(FILE *f)
{
    off_t pos = __ftello(f);
    if (pos > LONG_MAX) {
        errno = EOVERFLOW;
        return -1;
    }
    return pos;
}

weak_alias(__ftello, ftello);

weak_alias(ftello, ftello64);
